//
//  TMDataTable.m
//  clublbiza
//
//  Created by WANG TOM on 7/22/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "TMDataTable.h"
#import <objc/runtime.h>
#import <Foundation/Foundation.h>

@implementation TMDataTable
@synthesize tableName,pkName;
@synthesize dbContext;
@synthesize contextProvider;

-(TMDataTable *) initWithTablename:(NSString *)p_tableName withPKName:(NSString *)p_pkName contextProvider:(id<ITMTableCoreDataContectProvider>)p_contextProvider
{
    [super init];
    self.tableName = p_tableName;
    self.pkName = p_pkName;
    self.contextProvider = p_contextProvider;
    return self;
}
-(void) dealloc
{
    self.tableName = nil;
    [super dealloc];
}
-(NSManagedObjectContext *) dbContext
{
    return [self.contextProvider getCoreDataContext];
}
-(void) saveContect:(NSString *)functionName
{
    NSError *error = nil;;
    [self.dbContext save:&error];
    if(nil != error){
        
        NSException *exception =
        
        [NSException exceptionWithName:[NSString stringWithFormat:@"DataTable %@",functionName]                                reason:[error description]
         
                              userInfo:nil];
        
        @throw exception;
    }

}
-(NSManagedObject *) find:(NSString *) pkValue
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName 
                                              inManagedObjectContext:self.dbContext];
    [fetchRequest setEntity:entity];
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K=%@",self.pkName,pkValue];
 
   
    [fetchRequest setPredicate:predicate];
    
    NSError *error = nil;
    NSArray *fetchedObjects = [self.dbContext executeFetchRequest:fetchRequest error:&error];
    
    [fetchRequest release];
    if(nil != error){
        
        NSException *exception =
        
        [NSException exceptionWithName:@"DataTable find"
                                reason:[error description]
         
                              userInfo:nil];
        
        @throw exception;
    }
    
    return [fetchedObjects count] > 0?[fetchedObjects objectAtIndex:0]:nil;
}
-(NSArray *) findAll:(NSString *)condition withSort:(NSString *)sort
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName 
                                              inManagedObjectContext:self.dbContext];
    [fetchRequest setEntity:entity];
    
    if ( condition != nil ) {
        
        NSPredicate *predicate = [NSPredicate predicateWithFormat:condition];
        [fetchRequest setPredicate:predicate]; 
    }
    
    if ( sort != nil ) {
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sort ascending:YES];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
        [sortDescriptor release];
        
        [fetchRequest setSortDescriptors:sortDescriptors];
        [sortDescriptors release];
    
    }
    
    NSError *error = nil;
    NSArray *fetchedObjects = [self.dbContext executeFetchRequest:fetchRequest error:&error];
     [fetchRequest release];
    if(nil != error){
        
        NSException *exception =
        
        [NSException exceptionWithName:@"DataTable findAll"
                                reason:[error description]
         
                              userInfo:nil];
        
        @throw exception;
    }
    return fetchedObjects;

  
}
-(NSManagedObject *) findByField:(NSString *)fieldName withValue:(id)fieldValue withSort:(NSString*)sort
{
    NSString *condition = nil;
    
    if ( [fieldValue isKindOfClass:[NSNumber class]] ) {
        condition = [NSString stringWithFormat:@"%@=%@",fieldName,fieldValue];
    } else {
       condition = [NSString stringWithFormat:@"%@=%@",fieldName,fieldValue];
    }
    NSArray *objecs = [self findAll:condition withSort:sort] ;
    return  [objecs count] > 0 ? [objecs objectAtIndex:0]:nil;
}

-(void) addRow_core:(NSDictionary *)dataRow
{
    id insetedManagedObject = [NSEntityDescription insertNewObjectForEntityForName:self.tableName inManagedObjectContext:self.dbContext];
    [self copy_row_value:insetedManagedObject dataObject:dataRow];
    
}
-(void) copy_row_value:(id)dbObject dataObject:(NSDictionary *)dataValue
{
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList([dbObject class], &outCount);
    
    for(i = 0; i < outCount; i++) {
        
        objc_property_t property = properties[i];
        
       // NSLog(@"%s %s",property_getName(property), property_getAttributes(property));
        const char* propertyName = property_getName(properties[i]); 
        NSString *pName = [NSString  stringWithCString:propertyName encoding:NSUTF8StringEncoding];
        
       // SEL selector = NSSelectorFromString(pName);
        
        NSString *strValue = [dataValue objectForKey:pName];
        if(nil == strValue )
        {
            continue;
        }
       
       const char* strType = property_getAttributes(property);
        NSString *pType = [NSString stringWithCString:strType encoding:NSUTF8StringEncoding];
        
        id pValue =  strValue;
       
        
        if ( [pType rangeOfString:@"NSNumber"].location != NSNotFound ) {
             pValue =  [NSNumber numberWithInt:[strValue intValue]];
        }

        
        //[dbObject performSelector:selector withObject:pValue];
        [dbObject setValue:pValue forKey:pName];
    }
   free(properties);
}
-(void) addRow:(NSDictionary *)dataRow
{
 
    [self addRow_core:dataRow];
    [self saveContect:@"addRow"];
    
}
-(void) addRows:(NSArray *)dataRows
{
    for(NSDictionary *dataRow in dataRows ) {
         [self addRow_core:dataRow];
    }
   [self saveContect:@"addRows"];
    
}

-(void) saveRow_core:(NSDictionary *)dataRow
{
    NSString *pkValue = [dataRow objectForKey:self.pkName];
    if ( pkValue == nil) {
        [self addRow:dataRow];
        return;
    }
    id existRow = [self find:pkValue];
    if ( existRow ) {
        [self copy_row_value:existRow dataObject:dataRow];
    } else{
        [self addRow:dataRow];
    }
}
-(void) saveRow:(NSDictionary *)dataRow
{
 
    [self saveRow_core:dataRow];
     [self saveContect:@"saveRow"];
}
-(void) saveRows:(NSArray *)dataRows
{
    for(NSDictionary *dataRow in dataRows ) {
        [self saveRow_core:dataRow];
    }
    [self saveContect:@"saveRows"];
}
-(void) deleteRow:(NSString *) pkValue
{
    id existRow = [self find:pkValue];
    if ( nil != existRow ) {
        [self.dbContext deleteObject:existRow];
         [self saveContect:@"deleteRow"];
    }
}
-(void) deleteAll
{
    NSArray *data_list = [self findAll:nil withSort:nil];
    for(NSManagedObject *item in data_list) {
         [self.dbContext deleteObject:item];
    }
     [self saveContect:@"deleteAll"];
}
@end
